package org.datacoder.geocoding

import com.vividsolutions.jts.geom.*
import org.datacoder.geocoding.datastructures.geoshapes.*
import org.datacoder.geocoding.jurisdiction.*

class GeocodingUtils {

    public static final GeometryFactory geometryFactory = new GeometryFactory(new PrecisionModel(10000000000000000))
    private static final double MILES_PER_DEGREE = 69.047

    // Convert Jurisdiction, Geometry to GeoShape
    public static GeoPoint convertGeometryToGeoPoint(Geometry geometry){
        GeoPoint gp
        if(geometry instanceof Point){
            Point point = (Point)geometry
            gp = new GeoPoint(
                lon:point.x,
                lat:point.y
            )
        }else{
            Envelope envelope = geometry.getEnvelopeInternal()
            gp = new GeoPoint(
                lon:envelope.getMinX(),
                lat:envelope.getMinY()
            )
        }
        return gp
    }
    public static GeoRectangle convertGeometryToGeoRectangle(Geometry geometry){
        Envelope envelope = geometry.getEnvelopeInternal()
        GeoRectangle gr = new GeoRectangle(
            lon1:envelope.getMinX(),
            lon2:envelope.getMaxX(),
            lat1:envelope.getMinY(),
            lat2:envelope.getMaxY()
        )
        return gr
    }
    public static GeoInterval convertGeometryToGeoInterval(Geometry geometry, int type){
        Envelope envelope = geometry.getEnvelopeInternal()
        if(type == GeoShape.LON){
            GeoHzInterval ghi = new GeoHzInterval(
                lon1:envelope.getMinX(),
                lon2:envelope.getMaxX(),
                lat:envelope.getMinY()
            )
            return ghi
        }else{
            GeoVtInterval gvi = new GeoVtInterval(
                lon:envelope.getMinX(),
                lat1:envelope.getMinY(),
                lat2:envelope.getMaxY()
            )
            return gvi
        }
    }

    // Convert GeoShape to Jurisdiction
    public static Set<Jurisdiction> convertGeoShapesToJurisdictions(Collection<GeoShape> geoShapes){
        Set<Jurisdiction> jurisdictions = new HashSet<Jurisdiction>()
        for(gs in geoShapes){
            jurisdictions.add(gs.juris)
        }
        return jurisdictions
    }

    // Convert Units
    public static double convertMilesToLon(double lat, double miles){
        return (miles/MILES_PER_DEGREE) * Math.cos((Math.PI/180)*lat)
    }
    public static double convertMilesToLat(double miles){
        return miles/MILES_PER_DEGREE
    }

}

